using System;
using System.Data;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace needle.UI.Controls.Flat.Windows.Forms
{
	[System.ComponentModel.ToolboxItem(false)]
	public class ControlBase : System.Windows.Forms.UserControl, IHasStyleControl
	{
		//Style Neo, default!
		private Color m_BorderColor = Color.FromArgb(222, 217, 207);
		private Color m_BorderHotColor = Color.FromArgb(222, 217, 207);
		private StyleGuide m_enterpriseStyle = null;
		private bool parentStyle = false;
		private System.ComponentModel.Container components = null;

		protected System.Windows.Forms.ErrorProvider Errors;

		#region Constructors

		public ControlBase()
		{		
			InitializeComponent();
			SetStyle(ControlStyles.ResizeRedraw,true);
			SetStyle(ControlStyles.DoubleBuffer  | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint,true);
		}		

		#endregion

		#region Dispose

		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#endregion

		#region Component Designer generated code
		private void InitializeComponent()
		{
			components = new System.ComponentModel.Container();
			this.Errors = new System.Windows.Forms.ErrorProvider();
			// 
			// Errors
			// 
			this.Errors.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
			this.Errors.DataMember = null;
			// 
			// ControlBase
			// 
			this.Name = "ControlBase";
		}
		#endregion

		#region Events handlers

		protected void ChildCtrlMouseLeave(object sender,System.EventArgs e)
		{
			DrawControl(this.ContainsFocus);
		}

		protected void ChildCtrlMouseEnter(object sender,System.EventArgs e)
		{
			DrawControl(true);
		}

		#endregion

		#region Overrides

		protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
		{
			base.OnPaint(e);

			bool allowHot = (this.Enabled && !this.DesignMode) && !(this.IsMouseInControl && Control.MouseButtons == MouseButtons.Left && !this.ContainsFocus);
			bool hot = (this.IsMouseInControl || this.ContainsFocus) && allowHot;
			
			
			DrawControl(e.Graphics,hot);
		}

		protected override void OnMouseEnter(System.EventArgs e)
		{
			base.OnMouseEnter(e);
			DrawControl(true);
		}

		protected override void OnMouseLeave(System.EventArgs e)
		{
			base.OnMouseLeave(e);
			DrawControl(this.ContainsFocus);
		}

		protected override void OnGotFocus(System.EventArgs e)
		{
			base.OnGotFocus(e);
			DrawControl(this.ContainsFocus);
		}

		protected override void OnLostFocus(System.EventArgs e)
		{
			base.OnLostFocus(e);
			DrawControl(this.ContainsFocus);
		}

		protected override void OnControlAdded(ControlEventArgs e)
		{
			base.OnControlAdded(e);
			e.Control.MouseEnter += new System.EventHandler(this.ChildCtrlMouseEnter);
			e.Control.MouseLeave += new System.EventHandler(this.ChildCtrlMouseLeave);
		}

		protected override bool ProcessDialogKey(Keys keyData)
		{
			if (keyData == Keys.Enter)
			{
				this.OnEnterKeyPressed();
				return true;
			} 
			else if (keyData == Keys.Add)
			{
				this.OnPlusKeyPressed();
				return true;
			}

			return base.ProcessDialogKey(keyData);
		}

		#endregion

		#region Virtuals

		protected virtual void OnEnterKeyPressed()
		{
		}

		protected virtual void OnPlusKeyPressed() 
		{				
		}

		protected virtual void DrawControl(bool hot)
		{
			using(Graphics g = this.CreateGraphics())
			{
				DrawControl(g,hot);
			}
		}

		protected virtual void DrawControl(Graphics g,bool hot)
		{
            needle.UI.Controls.Flat.Windows.Forms.Helpers.GraphicsUtils.DrawBorder(g, this.m_BorderColor, this.m_BorderHotColor, this.ClientRectangle, hot);
		}

		protected virtual void OnStyleChanged(object sender, StyleEventArgs args)
		{
			if (args.PropertyName == "BorderColor") {this.BorderColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "BorderHotColor") {this.BorderHotColor = (Color)args.PropertyValue;}
		}

		protected virtual  void OnPlansOfColorsChanged(object sender, PlansOfColorsChangedEventArgs args)
		{
			if (m_enterpriseStyle !=null) 
			{
				this.BorderColor = m_enterpriseStyle.BorderColor;
				this.BorderHotColor = m_enterpriseStyle.BorderHotColor;
			}
		}

		#endregion

		#region Properties

		[Category("Style")]
		public StyleGuide Style
		{
			get {return m_enterpriseStyle;}
			set 
			{
				m_enterpriseStyle = value;

				if (m_enterpriseStyle != null)
				{
					PlansOfColorsChangedEventArgs oArgs = new PlansOfColorsChangedEventArgs(m_enterpriseStyle.PlansOfColors);
					OnPlansOfColorsChanged(this, oArgs);

					m_enterpriseStyle.StyleChanged += new StyleChangedEventHandler(this.OnStyleChanged);
					m_enterpriseStyle.PlansOfColorsChanged += new PlansOfColorsChangedEventHandler(this.OnPlansOfColorsChanged);
				}

				foreach(Control m_Control in this.Controls)
				{
					if (m_Control is IHasStyleControl && ((IHasStyleControl)m_Control).GetParentStyle()) 
					{
						((IHasStyleControl)m_Control).SetStyle(value);
					}
				}
			}
		}

		[Category("Behavior")]
		public bool ParentStyle
		{
			get {return parentStyle;}
			set {parentStyle = value;}
		}
		
		[Category("Style")]
		public Color BorderColor
		{
			get {return m_BorderColor;}
			set {m_BorderColor = value;}
		}

		[Category("Style")]
		public Color BorderHotColor
		{
			get {return m_BorderHotColor;}
			set {m_BorderHotColor = value;}
		}

		[Browsable(false)]
		public bool IsMouseInControl
		{
			get
			{
				Point mPos  = Control.MousePosition;
				bool retVal = this.ClientRectangle.Contains(this.PointToClient(mPos));
				return retVal;
			}
		}

		#endregion

		#region IHasStyleControl

		public StyleGuide GetStyle()
		{
			return this.m_enterpriseStyle;
		}

		public void SetStyle(StyleGuide style)
		{
			this.Style = style;
		}

		public bool GetParentStyle()
		{
			return this.parentStyle;
		}

		#endregion
	}
}
